#include "includes.h"
#include <termios.h>

static int comm_fd;
static int rs485_fd;

static int uart_init(char *name, int speed)
{
	int fd;
	struct termios stOpt;
	fd = Open(name, O_RDWR|O_NOCTTY);//O_NDELAY
	tcgetattr(fd, &stOpt);
	tcflush(fd, TCIOFLUSH);
	
	//boud 
	cfsetispeed(&stOpt, speed);
	cfsetospeed(&stOpt, speed);

	//8n1
	stOpt.c_cflag &= ~CSIZE;
	stOpt.c_cflag |= CS8;
	stOpt.c_cflag &= ~CSTOPB;	
	stOpt.c_cflag &= ~PARENB;
	stOpt.c_cflag &= ~CRTSCTS;
	stOpt.c_iflag &= ~INPCK;

	//row data
	stOpt.c_cflag |= (CLOCAL | CREAD);
	stOpt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	stOpt.c_iflag &= ~(ICRNL | INLCR |IXON | IXOFF | IXANY | ISTRIP);
	stOpt.c_oflag &= ~OPOST;
	stOpt.c_cc[VTIME] = 1; 
	stOpt.c_cc[VMIN] = 0;
	
	if (tcsetattr(fd, TCSANOW, &stOpt) != 0)
	{
		err_sys("%s tcsetattr error", name);
	}
	tcflush(fd, TCIOFLUSH);
	return fd;
}



int uart_dev_init()
{
	//comm_fd = uart_init("/dev/ttyS1", B115200);
	rs485_fd = uart_init("/dev/ttyS2", B38400);
	return 0;
}

void uart_cmd_open()
{
	//printf("_______________open start__________________\n");
	comm_fd = uart_init("/dev/ttyS1", B115200);
	//printf("_______________open after__________________\n");
}

void uart_cmd_close()
{
	close(comm_fd);
}

int uart_cmd_read(char *buf, int len)
{
	return Readn(comm_fd, buf, len);
}

void uart_cmd_write(char *buf, int len)
{
	Writen(comm_fd, buf, len);
}

void uart_cmd_flush()
{
	tcflush(comm_fd,TCIOFLUSH);
}

//ms:timeout
int uart_cmd(char *cmd, char *ack, int timeout)
{
	char buf[2048];
	time_t start_time, end_time;
	int ret;
	int i;
	int cnt = 0;
	fd_set fds;
	start_time = time(NULL);
	struct timeval time_value;
	err_msg("send the cmd: %s", cmd);
	uart_cmd_write(cmd, strlen(cmd)); //send the cmd
	if (!ack)
	{
		Sleep_us(timeout*1000);
		return 0;
	}

RECV:	
	time_value.tv_sec = 0;
	time_value.tv_usec = timeout*1000;


	FD_ZERO(&fds);
	FD_SET(comm_fd, &fds);
	ret = Select(comm_fd+1, &fds, NULL, NULL, &time_value);
	if (ret == 0)
	{
		err_msg("the cmd time out: %s ", cmd);
		return -1;
	}
	if (FD_ISSET(comm_fd, &fds))
	{
		cnt = uart_cmd_read(buf, sizeof(buf));
		printf("\n");
		for(i=0; i<cnt; i++)
		printf("%c ", buf[i]);
	}

	if (memstr(buf, cnt, ack) == NULL)
	{
		end_time = time(NULL);
		if ((end_time-start_time) <  timeout/1000)
		{
			//uart_cmd_write("\n", 1);
			goto RECV;
		}
		err_msg("1)the cmd: %s 2)can not recv %s", cmd, ack);
		return -1;
	}
	return 0;
}

int uart_rs485_read_timeout(char *buf, int len, int timeout)
{
	struct timeval time_value;
	fd_set fds;
	int ret;
	int cnt = 0;
	time_value.tv_sec = timeout;
	time_value.tv_usec = 0;
	
	
	FD_ZERO(&fds);
	FD_SET(rs485_fd, &fds);
	ret = Select(rs485_fd+1, &fds, NULL, NULL, &time_value);
	if (ret == 0)
	{
		//err_msg("the cmd time out: %s ", cmd);
		return -1;
	}
	if (FD_ISSET(rs485_fd, &fds))
	{
		cnt = uart_rs485_read(buf, len);
	}
	return cnt;
	
}

int uart_rs485_read(char *buf, int len)
{
	return Readn(rs485_fd, buf, len);
}

void uart_rs485_write(char *buf, int len)
{
	Writen(rs485_fd, buf, len);
}

